home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / SCLIB.ARJ / SCL1SAMP.EXE / BMPCNV.C < prev    next >
Text File  |  1992-01-01  |  11KB  |  414 lines

  1. /************************************************************************
  2.     This file reads a bitmap file (BMP) and creates a series of character
  3.     definition that make possible to display the bitmap in text mode
  4.     using SCL1 ModifyCharSet function.
  5.  
  6.     Horizontally the bitmap size in bits must a multiple (in pixels) of 8 and
  7.     of 16, 14 or 8 vertically depending of target monitor. The bitmap
  8.     can be displayed using the /D switch. The total number of characters
  9.     must be < than 32 (64 pixels x 64 is a good size). Run with /? switch 
  10.     for more information.
  11.  
  12.     Bitmaps can be created using Windows's Paintbrush. Use the Options Menu
  13.     Image Attributes to set size in pixels and 16 colors. Use only pure white 
  14.     and black colors.
  15.  
  16.     Several BMP files are included. Files that start with VGA are for VGA
  17.     and the ones that start with EGA are for EGA. Use the following command
  18.     (after compiling BMPCNV.C) to view:
  19.  
  20.         VGA monitors:               EGA monitors:
  21.  
  22.         BMPCNV /D VGABMP1           BMPCNV /D /B:14 EGABMP1
  23. ****************************************************************************/
  24.  
  25. #include <scl1.h>
  26. #include <stdlib.h>
  27.  
  28. /* structures used by to define BMP file header */
  29.  
  30. typedef unsigned int  WORD;
  31. typedef unsigned long DWORD;
  32.  
  33. typedef struct{
  34.         WORD    bfType;
  35.         DWORD   bfSize;
  36.         WORD    bfReserved1;
  37.         WORD    bfReserved2;
  38.         DWORD   bfOffBits;
  39.         }BITMAPFILEHEADER;
  40.  
  41. typedef struct{
  42.         DWORD      biSize;
  43.         DWORD      biWidth;
  44.         DWORD      biHeight;
  45.         WORD       biPlanes;
  46.         WORD       biBitCount;
  47.         DWORD      biCompression;
  48.         DWORD      biSizeImage;
  49.         DWORD      biXPelsPerMeter;
  50.         DWORD      biYPelsPerMeter;
  51.         DWORD      biClrUsed;
  52.         DWORD      biClrImportant;
  53.         }BITMAPINFOHEADER;
  54.  
  55. char HelpText[]= "Converts a bitmap file to a character definition table that can\n"
  56.                  "be used to modify EGA/VGA characters set.\n\n"
  57.                  "BMPCNV [/B:bytes] INFILE[.BMP] [OUTFILE[.C]]\n\n"
  58.                  "/B:bytes      specifies the number of bytes per character definition\n"
  59.                  "              values range from 8 to 32 (default = 16)\n"
  60.                  "INFILE[.BMP]  valid bitmap file to be converted\n"
  61.                  "[OUTFILE[.C]] output file created, if not specified BMPCNV\n"
  62.                  "              will use the name of the input file\n"
  63.                  "/D            Displays the bitmap, does not create output file\n";
  64.  
  65. main(int argc,char **argv)
  66. {
  67. BITMAPFILEHEADER bfh;
  68. BITMAPINFOHEADER bih;
  69. LLData lld;
  70. unsigned int bitbytes;
  71. int tchars,tcols,tlines,line,col,scanline,points=16,display=0,schar;
  72. unsigned char *p;
  73. int i,i2,j,k;
  74. unsigned int mask;
  75. int handle;
  76. char buffer[256];
  77. char infile[80];
  78. char outfile[80];
  79. unsigned char NewChar[16];
  80.  
  81. printf("\n\nBITMAP conversion utility (C) 1991 by J. R. Alvira\n\n");
  82.  
  83.     /* process command line arguments */
  84.  
  85. if(argc < 2)
  86.     {
  87.     printf(HelpText);
  88.     exit(-1);
  89.     }
  90.  
  91. for(i=1,j=0;i < argc;++i)
  92.     {
  93.     if(*argv[i]=='/' || *argv[i]=='-')
  94.         {
  95.         if(*(argv[i]+1) == 'B' || *(argv[i]+1) == 'b')
  96.             {
  97.             if(*(argv[i]+2) == ':')
  98.                 points=atoi(argv[i]+3);
  99.             else
  100.                 points=atoi(argv[i]+2);
  101.             }
  102.  
  103.         else if(*(argv[i]+1) == 'D' || *(argv[i]+1) == 'd')
  104.             display=1;
  105.  
  106.         else if(*(argv[i]+1) == '?')
  107.             {
  108.             printf(HelpText);
  109.             exit(0);
  110.             }
  111.         else
  112.             printf("Ignoring unknown switch %c\n",*(argv[i]+1));
  113.         }
  114.     else if(j==0)
  115.         {
  116.         strcpy(infile,argv[i]);
  117.         AddExtension(infile,"BMP");
  118.         ++j;
  119.         }
  120.     else
  121.         {
  122.         strcpy(outfile,argv[i]);
  123.         AddExtension(outfile,"C");
  124.         ++j;
  125.         }
  126.     }
  127.  
  128. if(points < 8 || points > 32)
  129.     {
  130.     printf("Illegal bytes value (8-32)\n");
  131.     exit(-1);
  132.     }
  133.  
  134. if(j == 1)
  135.     {
  136.     strcpy(outfile,infile);
  137.     ChangeExtension(outfile,"C");
  138.     }
  139.  
  140. if(OpenFile(infile,&handle,DOS2_RW))
  141.     {
  142.     printf("\nUnable to open %s\n\n",infile);
  143.     exit(-1);
  144.     }
  145.  
  146. if(ReadFile(handle,(char *)&bfh,sizeof(BITMAPFILEHEADER)))
  147.     {
  148.     CloseFile(handle);
  149.     printf("Error reading file header\n");
  150.     exit(-1);
  151.     }
  152.  
  153. if(bfh.bfType != 0x4d42)
  154.     {
  155.     CloseFile(handle);
  156.     printf("Not a valid bitmap file\n");
  157.     exit(-1);
  158.     }
  159.  
  160. if(ReadFile(handle,(char *)&bih,sizeof(BITMAPINFOHEADER)))
  161.     {
  162.     CloseFile(handle);
  163.     printf("Error reading info header\n");
  164.     exit(-1);
  165.     }
  166.  
  167. if(bih.biCompression)
  168.     {
  169.     CloseFile(handle);
  170.     printf("Bitmat data is compressed, cannot handle compressed format.\n");
  171.     exit(-1);
  172.     }
  173.  
  174. if((int)(bih.biWidth % 8))
  175.     {
  176.     CloseFile(handle);
  177.     printf("Bitmat width in pixels must be multiple of eight\n");
  178.     exit(-1);
  179.     }
  180.  
  181. if((int)(bih.biHeight % points))
  182.     {
  183.     CloseFile(handle);
  184.     printf("Bitmat height in pixels must be multiple of the number of bytes per character.\n");
  185.     exit(-1);
  186.     }
  187.  
  188.  
  189.     /* calculate number of character columns (8 bits) and lines using
  190.        BMP header information */
  191.  
  192. tcols=(int)(bih.biWidth / 8);
  193. tlines=(int)(bih.biHeight / points);
  194. tchars=tcols * tlines;
  195.  
  196.     /* calculate total number of bytes with bitmap data */
  197.  
  198. bitbytes=(unsigned int)(bfh.bfSize - bfh.bfOffBits);
  199.  
  200. printf("%i bytes of bitmap data\n",bitbytes);
  201. printf("Creating %i characters, %i bytes each (%i columns-%i lines)\n",tchars,points,tcols,tlines);
  202. printf("Width in pixels: %li\n",bih.biWidth);
  203. printf("Height in pixels: %li\n",bih.biHeight);
  204.  
  205. p=(unsigned char *)calloc(bitbytes,sizeof(char));   /* allocate buffer */
  206. if(p==0)
  207.     {
  208.     printf("Not enough memory to read bitmap data\n");
  209.     CloseFile(handle);
  210.     exit(-1);
  211.     }
  212.  
  213.     /* we'll use a linked list to process bitmap data */
  214.  
  215. LinkedList(LL_INIT,&lld);
  216. lld.DataSize=sizeof(char) * points;     /* size of each character */
  217.  
  218.     /* create a linked list node for each character */
  219.  
  220. for(i=0;i < tchars;++i)
  221.     {
  222.     lld.Data=p;
  223.     if(LinkedList(LL_ADD,&lld)==LL_MEM_ERROR)
  224.         {
  225.         printf("Not enough memory to process bitmap data\n");
  226.         CloseFile(handle);
  227.         exit(-1);
  228.         }
  229.     }
  230.  
  231.     /* move file pointer to the begining of bitmap data */
  232.  
  233. MoveFilePt2Offset(handle,bfh.bfOffBits);
  234. if(ReadFile(handle,p,bitbytes))             /* read data */
  235.     {
  236.     printf("Unable to read bit data\n");
  237.     CloseFile(handle);
  238.     exit(-1);
  239.     }
  240.  
  241.     /* conversion begins here */
  242.  
  243. mask=0x80;
  244. LinkedList(LL_FIRST,&lld);
  245.  
  246. for(line=0;line < tlines;++line)            /* process each character line */
  247.     {
  248.     LinkedList(LL_SAVE_POSITION,&lld);
  249.     for(scanline=points-1;scanline >= 0;--scanline)  /* each scanline (pixel) */
  250.         {
  251.         for(col=0;col < tcols;++col)        /* all characters in each line */
  252.             {
  253.             for(i=0,mask=0x80;i < 4;++i,++p)
  254.                 {
  255.                 if(((*p & 0xf0) >> 4))
  256.                     *(lld.Data+scanline) |= mask;
  257.                 mask >>= 1;
  258.  
  259.                 if((*p & 0x0f))
  260.                     *(lld.Data+scanline) |= mask;
  261.                 mask >>= 1;
  262.                 }
  263.             LinkedList(LL_NEXT,&lld);
  264.             }
  265.         LinkedList(LL_RESTORE_POSITION,&lld);
  266.         }
  267.     for(i=0;i < tcols;++i)
  268.         LinkedList(LL_NEXT,&lld);
  269.     }
  270.  
  271. if(display==0)      /* create file? */
  272.     {
  273.  
  274.     if(CreateFile(outfile,&handle,F_ARCHIVE))
  275.         {
  276.         printf("Unable to write C source file\n");
  277.         CloseFile(handle);
  278.         exit(-1);
  279.         }
  280.  
  281.     k=sprintf(buffer,"char CharDef[]={\r\n");
  282.     if(WriteFile(handle,buffer,k))
  283.         {
  284.         printf("Error writing C source file\n");
  285.         CloseFile(handle);
  286.         }
  287.     }
  288.  
  289. LinkedList(LL_LAST,&lld);
  290. for(i=0;i < tcols-1;++i)
  291.     LinkedList(LL_PREVIOUS,&lld);
  292.  
  293.         /* set video mode to correctly display bitmap */
  294.  
  295. VideoConfig();
  296. if(display==1 && (VC_Monitor==VC_VGA || VC_Monitor==VC_EGA))
  297.     {
  298.     printf("Press any key to view bitmap...\n");
  299.     GetKey();
  300.     if(VC_Monitor==VC_VGA)
  301.         {
  302.         switch(points)
  303.             {
  304.             case 16:
  305.                 SetVideoMode(3);
  306.                 break;
  307.             case 14:
  308.                 SetVideo28();
  309.                 break;
  310.             case 8:
  311.                 SetVideo4350();
  312.                 break;
  313.             default:
  314.                 display==-1;
  315.                 break;
  316.             }
  317.         }
  318.     if(VC_Monitor==VC_EGA)
  319.         {
  320.         switch(points)
  321.             {
  322.             case 14:
  323.                 SetVideoMode(3);
  324.                 break;
  325.             case 8:
  326.                 SetVideo4350();
  327.                 break;
  328.             default:
  329.                 display==-1;
  330.                 break;
  331.             }
  332.         if(tchars > 32)
  333.             {
  334.             printf("Bitmap is too big to display\n");
  335.             display=0;
  336.             }
  337.         }
  338.   }
  339.  
  340. if(display==1)
  341.     SetCurPos(tlines+2,0);
  342.  
  343. else if(display==-1)
  344.     {
  345.     printf("Your monitor does not support the characters scanlines\n");
  346.     exit(-1);
  347.     }
  348.  
  349. for(i=0,schar=192;i < tlines;++i)
  350.     {
  351.     LinkedList(LL_SAVE_POSITION,&lld);
  352.     for(i2=0;i2 < tcols;++i2,++schar)
  353.         {
  354.         for(j=0,k=0;j < points;++j)
  355.             {
  356.             k+=sprintf(buffer+k,"0x%02x,",(unsigned int)(unsigned char)(lld.Data[j]));
  357.  
  358.             if(display==1)
  359.                 NewChar[j]=(unsigned char)(lld.Data[j]);
  360.  
  361.             if(j==points-1)
  362.                 {
  363.                 if(i==tlines-1 && i2==tcols-1)
  364.                     {
  365.                     --k;
  366.                     k+=sprintf(buffer+k,"};\r\n\r\n");
  367.                     }
  368.                 else
  369.                     k+=sprintf(buffer+k,"\r\n");
  370.                 }
  371.             }
  372.  
  373.         if(display==1)
  374.             {
  375.             ModifyCharSet(points,schar,1,NewChar);
  376.             WriteChar(7,i,i2,1,schar);
  377.             }
  378.  
  379.         else if(WriteFile(handle,buffer,k))
  380.             {
  381.             printf("Error writing C source\n");
  382.             CloseFile(handle);
  383.             }
  384.  
  385.         LinkedList(LL_NEXT,&lld);
  386.         }
  387.     LinkedList(LL_RESTORE_POSITION,&lld);
  388.     for(j=0;j < tcols;++j)
  389.         LinkedList(LL_PREVIOUS,&lld);
  390.     }
  391.  
  392.  
  393. if(display==1)
  394.     {
  395.     printf("Press any key...\n");
  396.     GetKey();
  397.     InitVideo();
  398.     }
  399. else
  400.     {
  401.     if(CloseFile(handle))
  402.         {
  403.         printf("Error writing C source\n");
  404.         exit(-1);
  405.         }
  406.     else
  407.         printf("File %s has been created\n",outfile);
  408.     }
  409. }
  410.  
  411.  
  412.  
  413.  
  414.